package cn.dengta.webapp.im.entity;

import java.util.*;

import cn.dengta.context.model.WesKit;
import cn.dengta.webapp.base.entity.TimeBasedEntity;
import cn.dengta.webapp.trade.entity.meta.SpeedDatingRule;
import cn.dengta.webapp.user.model.Gender;
import cn.dengta.webapp.user.model.RecommendLevel;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import lombok.experimental.Accessors;
import me.codeplayer.util.Cmp;
import me.codeplayer.util.X;

/**
 * 速配队列
 *
 * @author Ready
 * @since 2022-07-22
 */
@Setter
@Getter
@Accessors(chain = true)
@TableName("im_speed_dating_queue")
public class SpeedDatingQueue extends TimeBasedEntity {

	/** 禁止匹配 */
	public static final Integer STATUS_DISABLED = 0,
	/** 等待匹配中 */
	STATUS_MATCHING = 1,
	/** 占用（匹配成功）中 */
	STATUS_LOCKED = 2;

	/** 进入 破冰 模式的男用户必须是 3 天以内注册的 */
	public static final int ICE_BREAKING_MAX_REGISTER_DAYS = 3;
	/** 进入 破冰 模式的男用户可免费拨打的秒数 */
	public static final int ICE_BREAKING_FREE_SECS = 0;
	/** 已经匹配过录制视频 */
	public static final int ICE_BREAKING_OK = 99;
	/** 破冰最大匹配次数 */
	public static final int ICE_BREAKING_MATCH_MAX_TIMES = 5;

	/** 用户ID */
	private Long userId;
	/** 性别：0=女；1=男 */
	private Integer gender;
	/** 偏好语言 */
	private Integer language;
	/** 匹配人群：1=自然人；2=AI */
	private Integer matchMain;
	/** 速配类型：1=聊天消息（Ai才有）;2=语音速配；3=视频速配；4=视频&语音 */
	private Integer type;
	/** 是否在速配池内：1=是；0=否 */
	private Integer inside;
	/** 状态：-99=禁止匹配；-1=占用中；0=场外；1=等待中 */
	private Integer status;
	/** 加入队列时间 */
	private Date joinTime;
	/** 最后活跃时间 */
	private Date lastActive;
	/** 是否白名单：1=是；0=否 ; 99=破冰 */
	private Integer whitelist;
	/** 白名单权重 */
	private Integer whiteSort;
	/** 当前用户所属分包 */
	private WesKit wesKit;

	@Setter(AccessLevel.NONE)
	@Getter(AccessLevel.NONE)
	public transient Set<Long> matched;

	public SpeedDatingQueue init(Long userId, Integer gender, Integer language, Integer type, Integer inside, Integer status, Integer whitelist, Integer whiteSort, WesKit wesKit, Date now) {
		this.userId = userId;
		this.gender = gender;
		this.language = language;
		this.type = type;
		this.inside = inside;
		this.status = status;
		this.joinTime = X.expectNotNull(joinTime, now);
		this.lastActive = now;
		this.whitelist = whitelist;
		this.whiteSort = whiteSort;
		this.wesKit = wesKit;
		this.initTime(now);
		return this;
	}

	public static int whitelist(int priority, final SpeedDatingRule rule) {
		if (rule.isVipRecFirst() && RecommendLevel.L11.value == priority
				|| rule.isRecFirst() && RecommendLevel.L10.value == priority) {
			return priority;
		}
		return 0;
	}

	public static final Comparator<SpeedDatingQueue> comparator = (o1, o2) -> {
		int cmp = -o1.getWhitelist().compareTo(o2.getWhitelist());
		if (cmp == 0) {
			cmp = o1.getLanguage().compareTo(o2.getLanguage());
			if (cmp == 0) {
				if (o1.getWhiteSort() == null) {
					return cmp;
				}
				cmp = -o1.getWhiteSort().compareTo(o2.getWhiteSort());
				if (cmp == 0) {
					cmp = o1.getUpdateTime().compareTo(o2.getUpdateTime());
				}
			}
		}
		return cmp;
	};

	public static Comparator<SpeedDatingQueue> getComparator(final SpeedDatingRule rule) {
		if (rule.isRecFirst() && rule.isVipRecFirst()) {
			return comparator;
		}
		return (o1, o2) -> {
			int cmp = -Integer.compare(whitelist(o1.getWhitelist(), rule), whitelist(o2.getWhitelist(), rule));
			if (cmp == 0) {
				cmp = o1.getLanguage().compareTo(o2.getLanguage());
				if (cmp == 0) {
					if (o1.getWhiteSort() == null || o2.getWhiteSort() == null) {
						return cmp;
					}
					cmp = -o1.getWhiteSort().compareTo(o2.getWhiteSort());
					if (cmp == 0) {
						cmp = o1.getUpdateTime().compareTo(o2.getUpdateTime());
					}
				}
			}
			return cmp;
		};
	}

	/**
	 * 指示当前用户是否来自破冰
	 */
	public boolean fromIceBreaking() {
		return Gender.MALE.eq(gender) && inside == 1 && Cmp.eq(whitelist, 99);
	}

	public boolean isVideo() {
		return Cmp.eq(this.type, 3) || Cmp.eq(this.type, 4);
	}

	public boolean isAudio() {
		return Cmp.eq(this.type, 2) || Cmp.eq(this.type, 4);
	}

	/** 是否Ai速配 */
	public boolean isAi(){
		return Cmp.eq(this.type, 1) && Cmp.eq(this.matchMain, 2);
	}

	public static final String USER_ID = "user_id";
	public static final String GENDER = "gender";
	public static final String LANGUAGE = "language";
	public static final String TYPE = "type";
	public static final String INSIDE = "inside";
	public static final String STATUS = "status";
	public static final String JOIN_TIME = "join_time";
	public static final String LAST_ACTIVE = "last_active";
	public static final String WHITELIST = "whitelist";
	public static final String MATCH_MAIN = "match_main";

}
